﻿using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace OpenLS.Spreadsheet.UI
{
    class SelectionOutline: Control
    {



        public bool IsFullRow
        {
            get { return (bool)GetValue(IsFullRowProperty); }
            set { SetValue(IsFullRowProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FullRow.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsFullRowProperty =
            DependencyProperty.Register("IsFullRow", typeof(bool), typeof(SelectionOutline), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));



        public bool IsFullColumn
        {
            get { return (bool)GetValue(IsFullColumnProperty); }
            set { SetValue(IsFullColumnProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FullColumn.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsFullColumnProperty =
            DependencyProperty.Register("IsFullColumn", typeof(bool), typeof(SelectionOutline), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));

        
        protected Geometry DefiningGeometry
        {
            get
            {
                PathGeometry result = new PathGeometry();
                PathFigure figure = new PathFigure(new Point(), GetSegments(), false);
                result.Figures.Add(figure);
                return result;

            }
        }
        protected Geometry BorderGeometry
        {
            get
            {
                PathGeometry result = new PathGeometry();
                PathFigure figure = new PathFigure(new Point(-1, -1), GetBorderSegments(), false);
                result.Figures.Add(figure);
                return result;

            }
        }

        private IEnumerable<PathSegment> GetBorderSegments()
        {
            return Enumerable.Select(GetBorderPoints(ActualWidth, ActualHeight, 6, 1), p => (PathSegment)new LineSegment(p, true));
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            
            base.OnRender(drawingContext);
            drawingContext.DrawGeometry(this.Background, null, DefiningGeometry);
            drawingContext.DrawGeometry(null, new Pen(Brushes.White, 1), BorderGeometry);
        }
        internal bool IsPenNoOp
        {
            get
            {
                double strokeThickness = this.BorderThickness.Left;
                if ((this.BorderThickness != null) && !double.IsNaN(strokeThickness))
                {
                    return false;
                }
                return true;
            }
        }


        private double Thickness = 3;

        private IEnumerable<PathSegment> GetSegments()
        {
            foreach (var point in GetBorderPoints( ActualWidth, ActualHeight, 6, 0))
                yield return new LineSegment(point, true);
            
        }

        private IEnumerable<Point> GetPoints(double ActualWidth, double ActualHeight, double m, double offset)
        {
            yield return new Point(ActualWidth, 0);
            yield return new Point(ActualWidth, ActualHeight - m);
            yield return new Point(ActualWidth - Thickness, ActualHeight - m);
            yield return new Point(ActualWidth - Thickness, Thickness);
            yield return new Point(Thickness, Thickness);
            yield return new Point(Thickness, ActualHeight - Thickness);
            yield return new Point(ActualWidth - m, ActualHeight - Thickness);
            yield return new Point(ActualWidth - m, ActualHeight);
            yield return new Point(0, ActualHeight);
            yield return new Point(0, 0);
        }
        private IEnumerable<Point> GetBorderPoints(double ActualWidth, double ActualHeight, double m, double offset)
        {
            if (IsFullColumn)
            {
                yield return new Point(ActualWidth + offset - m, -offset);
                yield return new Point(ActualWidth + offset - m, Thickness + offset);
                yield return new Point(Thickness + offset, Thickness + offset);
                yield return new Point(Thickness + offset, ActualHeight - Thickness - offset);
                yield return new Point(ActualWidth - Thickness - offset, ActualHeight - Thickness - offset);
                yield return new Point(ActualWidth - Thickness - offset, -offset + m + 1);
                yield return new Point(ActualWidth + offset, -offset + m + 1);
                yield return new Point(ActualWidth + offset, ActualHeight + offset);
                yield return new Point(-offset, ActualHeight + offset);
                yield return new Point(-offset, -offset);
            }
            else if (IsFullRow)
            {
                yield return new Point(ActualWidth + offset, -offset);
                yield return new Point(ActualWidth + offset, ActualHeight + offset);
                yield return new Point(-offset + m + 1, ActualHeight + offset);
                yield return new Point(-offset + m + 1, ActualHeight - Thickness - offset);
                yield return new Point(ActualWidth - Thickness - offset, ActualHeight - Thickness - offset);
                yield return new Point(ActualWidth - Thickness - offset, +Thickness + offset);
                yield return new Point(Thickness + offset, +Thickness + offset);
                yield return new Point(Thickness + offset, ActualHeight - m + offset);
                yield return new Point(-offset, ActualHeight - m + offset);
                yield return new Point(-offset, -offset);

            }
            else
            {
                yield return new Point(ActualWidth + offset, -offset);
                yield return new Point(ActualWidth + offset, ActualHeight + offset - m);
                yield return new Point(ActualWidth - offset - Thickness, ActualHeight + offset - m);
                yield return new Point(ActualWidth - offset - Thickness, Thickness + offset);
                yield return new Point(Thickness + offset, Thickness + offset);
                yield return new Point(Thickness + offset, ActualHeight - Thickness - offset);
                yield return new Point(ActualWidth + offset - m, ActualHeight - Thickness - offset);
                yield return new Point(ActualWidth + offset - m, ActualHeight + offset);
                yield return new Point(-offset, ActualHeight + offset);
                yield return new Point(-offset, -offset);
            }
        }
    }
}
